package com.ivanceras.client.widgets;

import java.util.HashMap;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.ivanceras.client.DataService;
import com.ivanceras.client.DataServiceAsync;
import com.ivanceras.shared.bo.Ad_table;
import com.ivanceras.shared.db.DAO;
import com.ivanceras.shared.db.Filter;
import com.ivanceras.shared.db.SerializableDAO;
import com.ivanceras.shared.db.SerializableFilter;

public class TabController {
	private final DataServiceAsync dataService = GWT
	.create(DataService.class);
	
	HashMap<String, Integer> paging = new HashMap<String, Integer>();
	HashMap<String, Boolean> lastRecord = new HashMap<String, Boolean>();
	Integer totalRecords = null;
	HashMap<String ,DAO[]> daoList = new HashMap<String, DAO[]>();
	HashMap<String, Integer> currentRecord = new HashMap<String, Integer>();

	public int itemPerPage = 10;
	Filter filter = null;
	AdTabUi tabUi = null;
	
	
	public TabController(AdTabUi tabUi, Integer itemsPerPage){
		this.tabUi = tabUi;
		if(itemsPerPage != null){
			this.itemPerPage = itemsPerPage;
		}
	}

	public void requestNextPage(Filter filter, final AsyncCallback<DAO[]> loadCallback){
		final String hash = getHash();
		setNextPage(hash);
		SerializableFilter sfilter = SerializableFilter.cast(filter);
		Ad_table table = tabUi.getAd_tab().getAd_table();
		retrieveTableData(table, getCurrentPage(hash), itemPerPage, sfilter, new AsyncCallback<DAO[]>(){

			@Override
			public void onFailure(Throwable caught) {
				loadCallback.onFailure(caught);
			}

			@Override
			public void onSuccess(DAO[] result) {
				addDAOContent(result);
				DAO[] incontextDaoList = daoList.get(hash);
				loadCallback.onSuccess(incontextDaoList);
				if(result.length < itemPerPage){
					lastRecord.put(hash, true);
					totalRecords = incontextDaoList.length;
				}
			}
			
		});
	}
	
	private void setNextPage(String hash){
		Integer currentPage = paging.get(hash);
		if(currentPage == null){
			currentPage = 0;
		}
		paging.put(hash, currentPage+1);
	}
	
	private int getCurrentPage(String hash){
		return paging.get(hash);
	}
	
	public void retrieveTableData(final Ad_table table, Integer page, Integer itemPerPage, SerializableFilter sfilter, final AsyncCallback<DAO[]> loadCallback) {
		System.out.println("Retrieving from table: "+table.getName());
		
		Ad_table ptable = new Ad_table();
		ptable.setAd_table_id(table.getAd_table_id());
		ptable.setTablename(table.getTablename());

		dataService.retrieveTableData(ptable, page, itemPerPage, null, sfilter, new AsyncCallback<SerializableDAO[]>() {

			@Override
			public void onFailure(Throwable caught) {
				loadCallback.onFailure(caught);
			}

			@Override
			public void onSuccess(SerializableDAO[] result) {
				DAO[] daoList = SerializableDAO.cast(result);
				loadCallback.onSuccess(daoList);
			}
		});
	}
	
	public void addDAOContent(DAO[] daoList){
		String hash = getHash();
		DAO[] origDao = this.daoList.get(getHash());
		if(origDao == null){
			this.daoList.put(hash, daoList);
			return;
		}
		else{
			DAO[] mergeDao = new DAO[origDao.length + daoList.length];
			System.arraycopy(origDao, 0, mergeDao, 0, origDao.length);
			System.arraycopy(daoList, 0, mergeDao, origDao.length, daoList.length);
			this.daoList.put(hash, mergeDao);
		}
	}
	private String getHash(){
		Filter filter = tabUi.windowController.getFilter(tabUi);
		AdTabUi parentTabUi = tabUi.windowController.getParentTabUi();
		
		String parentTableName = "";
		if(parentTabUi != null){
			parentTableName = parentTabUi.getAd_tab().getAd_table().getTablename();
			parentTableName = parentTableName.toLowerCase();
			System.err.println("parent tabui: "+parentTableName);
		}
		String filterValue = "";
		if(filter != null){
			if(filter.value != null){
				filterValue = filter.value.toString();
			}
		}
		String hash = parentTableName+filterValue;
		System.out.println("gethash: "+hash);
		return hash;
	}

	public void setCurrentRecordIndex(int recordIndex){
		this.currentRecord.put(getHash(), recordIndex);
	}
	public Integer getCurrentRecordIndex(){
		Integer currentRecord = this.currentRecord.get(getHash());
		if(currentRecord == null){
			return 0;
		}
		return currentRecord;
	}

}
